package gmp

import (
	"fmt"
	"net/http"
)

/*
* 1. 虽然多核处理器可以保证并行计算，但是实际中程序的数量以及 实际运行的线程数量会比CPU核心数多得多。
 2. 因此，为了平衡每个线程 能够被CPU处理的时间并最大化利用CPU资源，操作系统需要在适当的 时间通过定时器中断（Timer Interrupt）、I/O设备中断、系统调用时执行上下文切换（Context Switch）。

当发生线程上下文切换时，需要从操作系统用户
态转移到内核态，记录上一个线程的重要寄存器值（例如栈寄存器
SP）、进程状态等信息，这些信息存储在操作系统线程控制块
（Thread Control Block）中。当切换到下一个要执行的线程时，需
要加载重要的CPU寄存器值，并从内核态转移到操作系统用户态。如果
线程在上下文切换时属于不同的进程，那么需要更新额外的状态信息
及内存地址空间，同时将新的页表（Page Tables）导入内存。

1. 为啥说线程越多,切换越频繁  一直不明白一件事情，说线程不宜开得太多，太多的线程会导致线程频繁切换，消耗cpu时间。
对应单核机器而言 cpu的时间片为1s
如果只有1个线程  他几乎不用切换 只用干活         消耗时间 = 干活时间
如果有两个线程   线程1 执行一个时间片后  两个线程公平竞争cpu-> 这时 线程1 有50%的机会继续执行 不切换线程     消耗时间 = 干活时间 + 切换时间(少量)
如果有非常多的线程  线程1 执行一个时间片后 大概率抢不到cpu  这时线程1做时间的时间并不多                     消耗时间 = 干活时间 + 切换时间(大量)
如果是cpu密集的多线程程序    消耗时间 = 干活时间 + 切换时间(大量)
如果是io密集的多线程程序     消耗时间 = 干活时间 + 阻塞时间 + 切换时间(大量)   io密集型对线程切换友好  切换时间(大量) << 阻塞时间

协程的几个状态
idle 刚开始创建的状态     当先创建的协程初始化后会变为dead状态  dead状态也是协程销毁时的状态
runnable      协程在运行队列中,正在等待运行
running       协程正在被运行  已经被分配给了逻辑处理器和线程
waiting       协程在运行时被锁定 不能执行用户代码 在垃圾回收以及channel通信时经常会遇到这种情况
syscall       协程正在执行系统调用
preempted     协程被强制抢占后的状态
copystack     代表在进行协程栈扫描时发现需要扩容或缩小协程
栈空间，将协程中的栈转移到新栈时的状态。
scan  scanrunnable  scanrunning

main 协程
子协程
每个线程中都有一个特 殊的协程g0  协程g0运行在操作系统线程栈上，其作用主要是执行协程调度的
一系列运行时代码，而一般的协程无差别地用于执行用户代码。很显
然，执行用户代码的任何协程都不适合进行全局调度。
*/
func init() {

	links := []string{
		"http://www.baidu.com",
		"http://www.jd.com",
		"https://github.com/",
		"https://github.com/charlie93321/go_jvm",
		"https://github.com/fuzhengwei/CodeGuide/wiki",
		"https://nightlies.apache.org/flink/flink-docs-stable/",
		"file:///C:/Users/Administrator/Downloads/Go%E8%AF%AD%E8%A8%80%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86%E5%89%96%E6%9E%90.pdf",
	}

	ch := make(chan string, len(links))

	for _, link := range links {
		go checkLink(link, ch)
	}

	for i, _ := range links {
		value1 := <-ch
		fmt.Println(i, "=================>", value1)
	}
	defer close(ch)

}
func checkLink(link string, chp chan<- string) {
	//fmt.Println(link, "is start")
	_, err := http.Get(link)
	if err != nil {
		fmt.Println(err)
		fmt.Println(link, "is down")
		chp <- link
		return
	}
	chp <- link
	fmt.Println(link, "is up")
}
